package com.shrct.businessprocess.purchase.impl;

import com.google.common.collect.Iterables;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.product.RCAnonymousProductEntry;
import com.shrct.businessprocess.product.RCAnonymouseProductEntryRoot;
import com.shrct.businessprocess.product.RCProductSpecification;
import com.shrct.businessprocess.purchase.RCAnonymousContractProductItem;
import com.shrct.businessprocess.purchase.RCAnonymousProductInStockEvent;
import com.shrct.businessprocess.purchase.RCBaseProductPurchaseBudget;
import com.shrct.businessprocess.purchase.RCBudgetContract;
import com.shrct.businessprocess.purchase.RCProductAndQuantity;
import com.shrct.businessprocess.purchase.RCProductInStockEvent;
import com.shrct.businessprocess.purchase.impl.RCBudgetContractItemImpl;
import com.shrct.businessprocess.purchase.proxy.RCAnonymousContractProductItemProxy;
import edu.fudan.mylang.common.NumberExtensions;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import java.util.Set;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;

@Entity
@DiscriminatorValue("RCANONYMOUSCONTRACTPRODUCTITEM_TYPE")
public class RCAnonymousContractProductItemImpl extends RCBudgetContractItemImpl implements RCAnonymousContractProductItem {
  public RCAnonymousContractProductItemImpl() {
    super();
  }
  
  public RCAnonymousContractProductItemImpl(final RCBudgetContract contract) {
    super( contract);
    
  }
  
  public Iterable<RCProductAndQuantity> getInStockItems() {
    RCBudgetContract _contract = this.getContract();
    RCBudget _budget = _contract.getBudget();
    RCProductSpecification _productSpec = this.getProductSpec();
    Collection<? extends RCProductInStockEvent> _inStockEvents = ((RCBaseProductPurchaseBudget) _budget).getInStockEvents(_productSpec);
    Iterable<RCAnonymousProductInStockEvent> _filter = Iterables.<RCAnonymousProductInStockEvent>filter(_inStockEvents, RCAnonymousProductInStockEvent.class);
    final Function1<RCAnonymousProductInStockEvent,RCProductAndQuantity> _function = new Function1<RCAnonymousProductInStockEvent,RCProductAndQuantity>() {
        public RCProductAndQuantity apply(final RCAnonymousProductInStockEvent event) {
          RCProductAndQuantity _rCProductAndQuantity = new RCProductAndQuantity();
          final Procedure1<RCProductAndQuantity> _function = new Procedure1<RCProductAndQuantity>() {
              public void apply(final RCProductAndQuantity it) {
                RCAnonymouseProductEntryRoot _entityRoot = event.getEntityRoot();
                RCAnonymousProductEntry _hostEntry = _entityRoot.getHostEntry();
                it.setProduct(_hostEntry);
                RCAnonymouseProductEntryRoot _entityRoot_1 = event.getEntityRoot();
                Collection<RCAnonymousProductEntry> _entries = _entityRoot_1.getEntries();
                final Function1<RCAnonymousProductEntry,Integer> _function = new Function1<RCAnonymousProductEntry,Integer>() {
                    public Integer apply(final RCAnonymousProductEntry it) {
                      Integer _quantity = RCAnonymousContractProductItemImpl.this.getQuantity();
                      return _quantity;
                    }
                  };
                Iterable<Integer> _map = IterableExtensions.<RCAnonymousProductEntry, Integer>map(_entries, _function);
                final Function2<Integer,Integer,Integer> _function_1 = new Function2<Integer,Integer,Integer>() {
                    public Integer apply(final Integer i1, final Integer i2) {
                      int _plus = ((i1).intValue() + (i2).intValue());
                      return Integer.valueOf(_plus);
                    }
                  };
                Integer _reduce = IterableExtensions.<Integer>reduce(_map, _function_1);
                Integer _nullsafe = NumberExtensions.nullsafe(_reduce);
                it.setQuantity(_nullsafe);
              }
            };
          RCProductAndQuantity _doubleArrow = ObjectExtensions.<RCProductAndQuantity>operator_doubleArrow(_rCProductAndQuantity, _function);
          return _doubleArrow;
        }
      };
    Iterable<RCProductAndQuantity> _map = IterableExtensions.<RCAnonymousProductInStockEvent, RCProductAndQuantity>map(_filter, _function);
    return _map;
  }
  
  public Iterable<RCProductAndQuantity> getDeliverCandidates() {
    RCBudgetContract _contract = this.getContract();
    RCBudget _budget = _contract.getBudget();
    RCProductSpecification _productSpec = this.getProductSpec();
    Collection<? extends RCProductInStockEvent> _inStockEvents = ((RCBaseProductPurchaseBudget) _budget).getInStockEvents(_productSpec);
    Iterable<RCAnonymousProductInStockEvent> _filter = Iterables.<RCAnonymousProductInStockEvent>filter(_inStockEvents, RCAnonymousProductInStockEvent.class);
    final Function1<RCAnonymousProductInStockEvent,RCAnonymousProductEntry> _function = new Function1<RCAnonymousProductInStockEvent,RCAnonymousProductEntry>() {
        public RCAnonymousProductEntry apply(final RCAnonymousProductInStockEvent it) {
          RCAnonymouseProductEntryRoot _entityRoot = it.getEntityRoot();
          RCAnonymousProductEntry _hostEntry = _entityRoot.getHostEntry();
          return _hostEntry;
        }
      };
    Iterable<RCAnonymousProductEntry> _map = IterableExtensions.<RCAnonymousProductInStockEvent, RCAnonymousProductEntry>map(_filter, _function);
    Set<RCAnonymousProductEntry> _set = IterableExtensions.<RCAnonymousProductEntry>toSet(_map);
    final Function1<RCAnonymousProductEntry,RCProductAndQuantity> _function_1 = new Function1<RCAnonymousProductEntry,RCProductAndQuantity>() {
        public RCProductAndQuantity apply(final RCAnonymousProductEntry hostEntry) {
          RCProductAndQuantity _rCProductAndQuantity = new RCProductAndQuantity();
          final Procedure1<RCProductAndQuantity> _function = new Procedure1<RCProductAndQuantity>() {
              public void apply(final RCProductAndQuantity it) {
                it.setProduct(hostEntry);
                Integer _count = hostEntry.getCount();
                it.setQuantity(_count);
              }
            };
          RCProductAndQuantity _doubleArrow = ObjectExtensions.<RCProductAndQuantity>operator_doubleArrow(_rCProductAndQuantity, _function);
          return _doubleArrow;
        }
      };
    Iterable<RCProductAndQuantity> _map_1 = IterableExtensions.<RCAnonymousProductEntry, RCProductAndQuantity>map(_set, _function_1);
    return _map_1;
  }
  
  public static RCAnonymousContractProductItem create(final RCBudgetContract contract, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.purchase.RCAnonymousContractProductItem rCAnonymousContractProductItem = new com.shrct.businessprocess.purchase.impl.RCAnonymousContractProductItemImpl(
    	contract
    );
    objectFactory.create(rCAnonymousContractProductItem);
    return rCAnonymousContractProductItem;			
    
  }
  
  public static RCAnonymousContractProductItem createRCAnonymousContractProductItemImpl(final RCBudgetContract contract, final IObjectFactory objectFactory, final Procedure1<RCAnonymousContractProductItem> init) {
    com.shrct.businessprocess.purchase.RCAnonymousContractProductItem rCAnonymousContractProductItem = new com.shrct.businessprocess.purchase.impl.RCAnonymousContractProductItemImpl(
    	contract
    );
    objectFactory.create(rCAnonymousContractProductItem);
    init.apply(rCAnonymousContractProductItem);
    
    return rCAnonymousContractProductItem;			
    
  }
  
  public RCAnonymousContractProductItemProxy toProxy() {
    com.shrct.businessprocess.purchase.proxy.RCAnonymousContractProductItemProxy proxy = new com.shrct.businessprocess.purchase.proxy.RCAnonymousContractProductItemProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
